package com.ibm.rules.tree;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import com.google.common.collect.Lists;
import com.google.common.collect.Range;
import com.ibm.cps.message.ParsedDataMessage;
import com.ibm.rules.Rule;
import com.ibm.util.ErrorCode;
import com.ibm.util.exception.CPSException;

public class LeafRuleTreeNode extends RuleTreeNode {
	List<Rule> rules;

	public LeafRuleTreeNode(Rule[] rules) {
		this.rules = Lists.newArrayList(rules);
	}

	@SuppressWarnings("rawtypes")
	@Override
	public Collection<BigInteger> executeAllRules(Comparable[] fact) {
		Set<BigInteger> ids = new TreeSet<BigInteger>();
		Iterator<Rule> iter = rules.iterator();
		while(iter.hasNext()){
			Rule now = iter.next();
			if (now.eval(fact))
				ids.add(now.getRuleID());
		}
		return ids;
	}
	
	@SuppressWarnings("rawtypes")
	@Override
	public Collection<BigInteger> executeAllRules(ParsedDataMessage Msg) {
		Set<BigInteger> ids = new TreeSet<BigInteger>();
		Iterator<Rule> iter = rules.iterator();
		while(iter.hasNext()){
			Rule now = iter.next();
			if (now.eval(Msg))
				ids.add(now.getRuleID());
		}
		return ids;
	}

	public Rule[] getRules() {
		return rules.toArray(new Rule[rules.size()]);
	}

	public <T extends Comparable<T>> void removeRedundantCondition(int tagId,
			Range<T> range) {
		Iterator<Rule> iter = rules.iterator();
		while(iter.hasNext()){
			iter.next().eraseCondition(tagId, range);
		}
	}

	public void refine() {
		Set<Rule> ruleSet = new TreeSet<Rule>();
		Iterator<Rule> iter = rules.iterator();
		while(iter.hasNext()){
			ruleSet.add(iter.next().refine());
		}
		rules = new ArrayList<>(ruleSet);
	}
	
	public boolean addIncrementalRule(Rule rule) throws CPSException{
		rules.add(rule);
		if(rules.size() > SPLIT_THRESHOLD)
			return false;
		else return true;
	}

	@Override
	public void deleteRuleByName(String ruleName) throws CPSException {
		throw new CPSException(ErrorCode.NO_IMPLEMENTATION_CODE,
				"do not support delete rule");
	}

}
